AWS ParallelCluster Ubuntu 22.04 で Mountpoint for Amazon S3 を使ってヘッドノードとコンピュートノードに S3 バケットを自動マウントする方法
AWS ParallelCluster を使った HPC クラスターの運用において、データの共有方法と保存コストは大きな課題です。本記事では Mountpoint for Amazon S3 を活用し、ヘッドノードとコンピュートに S3 バケットの自動マウントを実現する方法を紹介します。これにより、クラスター間でのデータ共有と、コスト効率の高いデータの長期保存が可能になります。
構成概要
本記事で紹介する構成の概要を以下の図に示します。ヘッドノードとコンピュートノードに S3 バケットがマウントされます。ヘッドノードでは systemd サービスによって自動マウントが行われ、コンピュートノードでは起動時に mount-s3 コマンドが実行されます。
本記事の目的と解決する課題
以前、AWS ParallelCluster の Ubuntu 22.04 に対応した Moutpoint for Amazon S3 の利用方法を紹介しました。クラスターの運用をする中でいくつかの課題が見えてきたためブラッシュアップしました。
本記事では、以下の 2 点を改善した Mountpoint for Amazon S3 の活用方法を紹介します。
- カスタムブートストラップスクリプトと systemd を使ってヘッドノードに S3 バケットを自動マウントする
- クラスターのコンフィグからマウント設定を引数で渡し、マウント用スクリプトの再利用性を高める
これにより、S3 バケットのマウント作業を自動化し、運用の手間を削減できます。また、マウント設定をクラスターコンフィグで一元管理できるため、スクリプトの管理コストを抑えます。
それでは、具体的な手順を見ていきましょう。
実装手順
クラスター構築に必要な要素は大きく分けて 3 つあります。
- カスタムブートストラップスクリプト
- IAM ポリシー
- クラスターのコンフィグ
それぞれについて詳しく見ていきましょう。
カスタムブートストラップスクリプトの作成
カスタムブートストラップスクリプトは、ヘッドノードとコンピュートノードの起動時に実行されるスクリプトです。今回は以下の 3 つのスクリプトを用意しました。
- 共通 Mountpoint for Amazon S3 インストールスクリプト
- ヘッドノードとコンピュートノードの両方で実行され、Mountpoint for Amazon S3 をインストールします。
- コンピュートノード用 S3 バケットマウントスクリプト
- コンピュートノードの起動時に実行され、mount-s3 コマンドを使って S3 バケットをマウントします。
- マウントに必要な情報はクラスターのコンフィグから引数で渡します。
- ヘッドノード用 S3 バケットマウントスクリプト
- ヘッドノードの初回起動時に実行され、systemd サービスを作成して S3 バケットを自動マウントします。
- マウントに必要な情報はクラスターのコンフィグから引数で渡します。
共通 Mountpoint for Amazon S3 インストールスクリプト
ヘッドノード、コンピュートノードの初回起動時に Mountpoint for Amazon S3 をインストールします。
項目名 | 値 |
---|---|
ファイル名 | install.sh |
保存先 | 任意の S3 バケット |
#! /bin/bash # Install mount-s3 command for Ubuntu 22.04 sudo apt-get update sudo apt-get install libfuse2 -y wget -P /tmp https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb sudo apt-get install /tmp/mount-s3.deb -y
コンピュートノード用 S3 バケットマウントスクリプト
コンピュートノードの起動時にmount-s3
コマンドを実行し S3 バケットをマウントします。
コンピュートノードは、ジョブの実行に合わせて動的に起動・終了するため、起動のたびに mount-s3
コマンドでマウントを行う設定としています。
項目名 | 値 |
---|---|
ファイル名 | mount.sh |
保存先 | 任意の S3 バケット |
#! /bin/bash BUCKET_NAME=$1 TARGET_DIRECTORY=$2 OPTIONS=$3 # Allow other users to access mount # Needed if --allow-root or --allow-other option is set if ! grep -q "^user_allow_other" /etc/fuse.conf then echo "user_allow_other" | sudo tee -a /etc/fuse.conf fi sudo mkdir -p ${TARGET_DIRECTORY} sudo chmod 777 ${TARGET_DIRECTORY} sudo mount-s3 ${OPTIONS} ${BUCKET_NAME} ${TARGET_DIRECTORY}
ヘッドノードノード用 S3 バケットマウントスクリプト
ヘッドノードノードの初回起動時に systemd で Moutpoint 用のサービスを作成します。以降はサービスの起動により S3 バケットを自動マウントします。コンピュートノードのスクリプトと同様にマウント対象の S3 バケットや、マウントパスはクラスターのコンフィグから引数で渡します。
項目名 | 値 |
---|---|
ファイル名 | mount-headnode.sh |
保存先 | 任意の S3 バケット |
#! /bin/bash BUCKET_NAME=$1 TARGET_DIRECTORY=$2 OPTIONS=$3 # Generate a distinct identifier to allow multiple mountpoint-s3 services SERVICE_ID=$(echo -n "${BUCKET_NAME}:${TARGET_DIRECTORY}" | md5sum | awk '{print $1}') SERVICE_ID=${SERVICE_ID:0:8} SERVICE_NAME="mountpoint-s3-${SERVICE_ID}" # Allow other users to access mount # Needed if --allow-root or --allow-other option is set if ! grep -q "^user_allow_other" /etc/fuse.conf then echo "user_allow_other" | sudo tee -a /etc/fuse.conf fi # Create mount TARGET_DIRECTORY sudo mkdir -p ${TARGET_DIRECTORY} sudo chmod 777 ${TARGET_DIRECTORY} # Create service file tee > "${SERVICE_NAME}.service" <<EOF [Unit] Description=Mount s3://${BUCKET_NAME} at ${TARGET_DIRECTORY} Wants=network-online.target After=default.target AssertPathIsTARGET_DIRECTORY=${TARGET_DIRECTORY} [Service] Type=forking User=ubuntu Group=ubuntu ExecStart=/usr/bin/mount-s3 ${OPTIONS} ${BUCKET_NAME} ${TARGET_DIRECTORY} ExecStop=/usr/bin/fusermount -u ${TARGET_DIRECTORY} [Install] WantedBy=default.target EOF # Install and start the service sudo mv "${SERVICE_NAME}.service" /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable "${SERVICE_NAME}" sudo systemctl start "${SERVICE_NAME}"
IAM ポリシーの作成
S3 バケットをマウントするには、ヘッドノードとコンピュートノードにアクセス権限を付与する必要があります。今回は以下の IAM ポリシーを作成し、ヘッドノードとコンピュートノードの IAM ロールにアタッチします。
マウントした S3 バケット用にアクセスするための権限
マウント対象となる S3 バケットに対してヘッドノード、コンピュートノードからアクセスするために必要な権限を付与します。ヘッドノード、コンピュートノードからマウントした S3 バケットに対してファイルの読み書きができるように s3:DeleteObject
の権限を持たせています。
項目名 | 値 |
---|---|
ポリシー名 | hpc-dev-AllowMountpointForS3 |
アタッチ先 | ヘッドノード、コンピュートノードの IAM ロール(クラスターのコンフィグで指定) |
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::hpc-dev-mountpoint-sample-1", "arn:aws:s3:::hpc-dev-mountpoint-sample-2" ], "Effect": "Allow" }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:AbortMultipartUpload", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::hpc-dev-mountpoint-sample-1/*", "arn:aws:s3:::hpc-dev-mountpoint-sample-2/*" ], "Effect": "Allow" } ] }
以下のブログで、S3 バケットを作成と同時に上記の IAM ポリシーを作成する CloudFormation テンプレートを紹介しています。
クラスターのサンプルコンフィグ
クラスターのコンフィグを紹介します。ここではヘッドノードとコンピュートノードの設定を中心に解説します。
コンフィグファイル全文
先にコンフィグファイル全文を掲載します。
Region: ap-northeast-1 Image: Os: ubuntu2204 Tags: - Key: Name Value: mountS3-v391 # ---------------------------------------------------------------- # Head Node Settings # ---------------------------------------------------------------- HeadNode: InstanceType: m7i-flex.large Networking: ElasticIp: false SubnetId: subnet-0c82bb28e119e2aa8 Ssh: KeyName: org-sandbox-keypair LocalStorage: RootVolume: Size: 40 Encrypted: true VolumeType: gp3 Iops: 3000 Throughput: 125 Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 S3Access: - BucketName: hpc-custom-boostrap-files EnableWriteAccess: false CustomActions: OnNodeConfigured: Sequence: - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh Args: - hpc-dev-mountpoint-sample-1 - /mnt/s3-readonly - "--allow-delete --allow-other" - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh Args: - hpc-dev-mountpoint-sample-2 - /mnt/s3 - "--allow-delete --allow-other" # ---------------------------------------------------------------- # Compute Node Settings # ---------------------------------------------------------------- Scheduling: Scheduler: slurm SlurmSettings: ScaledownIdletime: 5 SlurmQueues: # ------ Compute 1 ------ - Name: p1 ComputeResources: - Name: m6idmetal Instances: - InstanceType: m6id.metal MinCount: 0 MaxCount: 30 DisableSimultaneousMultithreading: true ComputeSettings: LocalStorage: RootVolume: Size: 40 Encrypted: true VolumeType: gp3 Iops: 3000 Throughput: 125 CapacityType: SPOT AllocationStrategy: capacity-optimized Networking: SubnetIds: - subnet-0c82bb28e119e2aa8 - subnet-0296a0c8515ed3bdc - subnet-0089ff187d1f54258 PlacementGroup: Enabled: false Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 S3Access: - BucketName: hpc-custom-boostrap-files EnableWriteAccess: false CustomActions: OnNodeConfigured: Sequence: - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh Args: - hpc-dev-mountpoint-sample-1 - /mnt/s3-readonly - "--read-only --allow-other" - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh Args: - hpc-dev-mountpoint-sample-2 - /mnt/s3 - "--allow-delete --allow-other" # ---------------------------------------------------------------- # Shared Storage Settings # ---------------------------------------------------------------- SharedStorage: - MountDir: /mnt/efs-elastic Name: efs1 StorageType: Efs EfsSettings: FileSystemId: fs-0846dc947572a66a1 - MountDir: /mnt/efs-bursting Name: efs2 StorageType: Efs EfsSettings: FileSystemId: fs-046b02d3ba107c2b2 # ---------------------------------------------------------------- # Other Settings # ---------------------------------------------------------------- Monitoring: Logs: CloudWatch: Enabled: true RetentionInDays: 180 DeletionPolicy: "Delete" Dashboards: CloudWatch: Enabled: true
ヘッドノードの設定解説
AdditionalIamPolicies:
セクションで、マウントした S3 バケットへの必要なアクセス権限を付与した IAM ポリシーを指定します。
また、カスタムブートストラップスクリプトが保存されている S3 バケットへの権限が必要なため、S3Access:
セクションでスクリプト保存先の S3 バケットへ対して読み取り権限を付与しています。
Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 S3Access: - BucketName: hpc-custom-boostrap-files EnableWriteAccess: false
CustomActions:
セクションでは、ヘッドノードの起動時に実行するカスタムブートストラップスクリプトを指定します。
まず、install.sh
スクリプトで Mountpoint for Amazon S3 をインストールします。
次に、mount-for-headnode.sh
スクリプトを 2 回呼び出し、異なる S3 バケットを異なるマウントポイントにマウントしています。このスクリプトは、systemd サービスを作成し、ヘッドノードの起動時に自動的に S3 バケットをマウントします。
スクリプトの引数には、以下の 3 つを指定しています。
- マウント対象の S3 バケット名
- マウントするディレクトリのパス
mount-s3
コマンドのオプション指定
これにより、S3 バケット hpc-dev-mountpoint-sample-1
を /mnt/s3-readonly
にマウントし、hpc-dev-mountpoint-sample-2
を/mnt/s3
に同じスクリプトを利用してマウントを実現します。マウントオプションで --allow-delete
と --allow-other
を指定し、他のユーザーからのアクセスを許可しつつ、ファイルの削除を可能にしています。/mnt/s3-readonly
という名前なのに削除を許可している理由は、コンピュートノードとマウントするディレクトリ名を統一しているためです。ヘッドノードからは読み書きできた方が便利だったため、書き込めるようにしています。
CustomActions: OnNodeConfigured: Sequence: - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh Args: - hpc-dev-mountpoint-sample-1 - /mnt/s3-readonly - "--allow-delete --allow-other" - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount-for-headnode.sh Args: - hpc-dev-mountpoint-sample-2 - /mnt/s3 - "--allow-delete --allow-other"
コンピュートノードの設定解説
コンピュートノードの設定は、ヘッドノードと同様にIam:
セクションで IAM ポリシーと S3 バケットへのアクセス権を付与しています。
Iam: AdditionalIamPolicies: - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - Policy: arn:aws:iam::123456789012:policy/hpc-dev-AllowMountpointForS3 S3Access: - BucketName: hpc-custom-boostrap-files EnableWriteAccess: false
CustomActions:
セクションでは、コンピュートノードの起動時に実行するカスタムブートストラップスクリプトを指定します。
まず、install.sh
スクリプトで Mountpoint for Amazon S3 をインストールします。
次に、mount.sh
スクリプトを 2 回呼び出し、異なる S3 バケットを異なるマウントポイントにマウントしています。このスクリプトは、mount-s3
コマンドを使って S3 バケットをマウントします。
スクリプトの引数には、以下の 3 つを指定しています。
- マウント対象の S3 バケット名
- マウントするディレクトリのパス
mount-s3
コマンドのオプション指定
hpc-dev-mountpoint-sample-1
のマウントオプションでは、--read-only
を指定し、読み取り専用でマウントしています。一方、hpc-dev-mountpoint-sample-2
では、--allow-delete
を指定し、ファイルの削除を可能にしています。どちらのマウントポイントでも--allow-other
オプションを指定し、他のユーザーからのアクセスを許可しています。
CustomActions: OnNodeConfigured: Sequence: - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/install.sh - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh Args: - hpc-dev-mountpoint-sample-1 - /mnt/s3-readonly - "--read-only --allow-other" - Script: s3://hpc-custom-boostrap-files/mountpoint-for-ubuntu22/mount.sh Args: - hpc-dev-mountpoint-sample-2 - /mnt/s3 - "--allow-delete --allow-other"
動作検証
前述のサンプルコンフィグより構築したクラスターで Mountpoint for Amazon S3 が正常に動作することを確認します。ヘッドノードとコンピュートノードそれぞれで、S3 バケットがマウントされていることを検証します。
ヘッドノードのマウント状況確認
ヘッドノードにログインし、以下のコマンドを実行して Mountpoint for Amazon S3 のサービスが正常に起動していることを確認します。
$ systemctl list-units | grep mountpoint-s3 mountpoint-s3-585e79a6.service loaded active running Mount s3://hpc-dev-mountpoint-sample-2 at /mnt/s3 mountpoint-s3-91ef1212.service loaded active running Mount s3://hpc-dev-mountpoint-sample-1 at /mnt/s3-readonly
以下のコマンドの出力から、2 つの S3 バケットが指定したディレクトリにマウントされていることが確認できます。
$ ls /mnt/s3 YouCanLookThisFileFromS3.txt $ ls /mnt/s3-readonly/ YouCanLookThisFileFromS3.txt images reads
ヘッドノードの EC2 インスタンスを停止し、再度開始した場合でも、systemd サービスによって S3 バケットが自動的にマウントされることを確認します。
以下は、インスタンス開始後のサービスの状態とマウント状況です。
$ systemctl list-units | grep mountpoint-s3 mountpoint-s3-585e79a6.service loaded active running Mount s3://hpc-dev-mountpoint-sample-2 at /mnt/s3 mountpoint-s3-91ef1212.service loaded active running Mount s3://hpc-dev-mountpoint-sample-1 at /mnt/s3-readonly
systemd サービスが自動的に起動し、S3 バケットがマウントされていることがわかります。
$ mount | grep mountpoint-s3 mountpoint-s3 on /mnt/s3-readonly type fuse (rw,nosuid,nodev,noatime,user_id=1000,group_id=1000,default_permissions,allow_other) mountpoint-s3 on /mnt/s3 type fuse (rw,nosuid,nodev,noatime,user_id=1000,group_id=1000,default_permissions,allow_other)
コンピュートノードのマウント状況確認
コンピュートノードで S3 バケットがマウントされていることを確認するために、適当なテストジョブをサブミットしコンピュートノードを起動させます。
起動してきたコンピュートノードにログインし、以下のコマンドの出力から 2 つの S3 バケットが指定したディレクトリにマウントされていることが確認できます。
$ ls /mnt/s3 YouCanLookThisFileFromS3.txt $ ls /mnt/s3-readonly/ YouCanLookThisFileFromS3.txt images reads
/mnt/s3-readonly
は read-only オプションが指定されており、読み取り専用(ro
)でマウントされています。一方、/mnt/s3
では allow-delete オプションが指定されており、ファイルの読み書き(rw
)が可能になっています。
$ mount | grep mountpoint-s3 mountpoint-s3 on /mnt/s3-readonly type fuse (ro,nosuid,nodev,noatime,user_id=0,group_id=0,default_permissions,allow_other) mountpoint-s3 on /mnt/s3 type fuse (rw,nosuid,nodev,noatime,user_id=0,group_id=0,default_permissions,allow_other)
まとめ
本記事では、AWS ParallelCluster の Ubuntu 22.04 環境で Mountpoint for Amazon S3 を活用し、ヘッドノードとコンピュートノードに S3 バケットを自動マウントする方法を紹介しました。カスタムブートストラップスクリプトと systemd を使うことで、クラスター起動時に S3 バケットを自動的にマウントできます。また、クラスターのコンフィグでマウント設定を一元管理することで、マウントスクリプトの管理コストを削減できます。
おわりに
Mountpoint for Amazon S3 を活用することで、AWS ParallelCluster でのデータ共有と永続化が容易になります。今後は、ゲノム解析のワークロードで Mountpoint for Amazon S3 を活用し、利便性と効率性を高める検証を進めていきます。